% Class "Joystick"
%
% *Methods*
% - getX
% - getY
% - getXY
% - getXYt
%
%
% *Example*
% 
% When you're really done, close the object. This will close and cleanup all the
% referes to the serial port.
%
%  j = Joystick('com1');
% 
%  [x, y] = j.getXY();
%  ... do more stuff here
%  ...
%
%  j.close();
%
%
% If called with an empty com port string, no serial connection will be
% established. The serial commands will be echo'd to stdout:
%
%  j = Joystick('')
%  ...
%
%
% *Protocol*
% Custom protocol for the Joystick:
%
% x -> Get X coordinate
% y -> Get Y coordinate
% z -> Get both X and Y coordinates seperated by a comma
% a -> Get X, Y and the time in miliseconds, seperated by a comma
%
% t -> Toggle test mode. In test mode, every 25 miliseconds a coordinate will
%      be sent. Send another 't' to stop.


classdef Joystick
    
    properties (SetAccess = public)
        serobj;
        debugmode = false;
    end
    
    methods
        function J = Joystick(comport)
            if (strcmp(comport, ''))
                fprintf('Joystick: No Com port given, running in debug mode...\n')
                J.debugmode = true;
            end
            
            if (not(J.debugmode))
                delete(instrfind);
                J.serobj = serial(comport);
                
                % serial port configuration
                set(J.serobj, 'Baudrate',        115200);
                set(J.serobj, 'Parity',          'none');
                set(J.serobj, 'Databits',        8);       % number of data bits
                set(J.serobj, 'StopBits',        1);       % number of stop bits
                set(J.serobj, 'Terminator',      'CR/LF'); % line ending character
                % see also:
                % http://www.mathworks.com/matlabcentral/newsreader/view_original/292759
                
                %set(J.serobj, 'InputBufferSize', 1);       % set read buffBuffer for read
                set(J.serobj, 'FlowControl',     'none');   %
                
                % open the serial port
                fopen(J.serobj);
                
                % since matlab pulls the DTR line, the arduino will reset
                % so we have to wait for the initialization of the controller
                oldState = pause('query');
                pause on;
                pause(2.5);
                pause(oldState);
                
                % firmware responds with 'Joystick: $Revision XX:$, ready!'
                status = J.receive();
                fprintf('Joystick says: %s', status);
            end
        end
        
        % getX
        % returns the current X coordinate
        function x = getX(J)
            cmd = 'x';
            J.sendcmd(cmd);
            x = J.receive();
        end
        
        % getY
        % returns the current Y coordinate
        function y = getY(J)
            cmd = 'y';
            J.sendcmd(cmd);
            y = J.receive();
        end
        
        % getXY
        % returns the current X and Y coordinate
        function [x, y] = getXY(J)
            cmd = 'z';
            J.sendcmd(cmd);
            xy = sscanf(J.receive(), '%i,%i');
            
            x = xy(1);
            y = xy(2);
        end
        
        % getXYt
        % returns the current X and Y coordinate
        function [x, y, t] = getXYt(J)
            cmd = 'a';
            J.sendcmd(cmd);
            xyt = sscanf(J.receive(), '%i,%i,%i');
            
            x = xyt(1);
            y = xyt(2);
            t = xyt(3);
        end
        
 
        function sendcmd(J, cmd)
            if (J.debugmode)
                fprintf('Joystick: sending: ');
                fprintf(cmd);
                fprintf('\n');
            else
                fprintf(J.serobj, cmd);
            end
        end
        
        function response = receive(J)
            if (J.debugmode)
                fprintf('Joystick: listening...');
                fprintf('\n');
                response = '';
            else
                response = fscanf(J.serobj);
            end
        end
        
        % close
        function close(J)
            if (not(J.debugmode))
                fclose(J.serobj);
                delete(J.serobj);
            end
        end
    end
end
